xtask\tasks\fmt\house_rules/
autogen_comment.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use anyhow::anyhow;
5use fs_err::File;
6use std::ffi::OsStr;
7use std::io::BufRead;
8use std::io::BufReader;
9use std::io::Write;
10use std::path::Path;
11
12const AUTOGEN_COMMENT: &str = "# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html";
13
14pub fn check_autogen_comment(path: &Path, fix: bool) -> anyhow::Result<()> {
15    if path.file_name() != Some(OsStr::new("Cargo.toml")) {
16        return Ok(());
17    }
18
19    let f = BufReader::new(File::open(path)?);
20    let mut found = false;
21    for line in f.lines() {
22        let line = line?;
23        if line.trim() == AUTOGEN_COMMENT {
24            found = true;
25            break;
26        }
27    }
28
29    if found && fix {
30        let path_fix = &{
31            let mut p = path.to_path_buf();
32            let ok = p.set_extension("toml.fix");
33            assert!(ok);
34            p
35        };
36
37        let f = BufReader::new(File::open(path)?);
38        let mut f_fixed = File::create(path_fix)?;
39
40        let mut just_fixed = false;
41        for line in f.lines() {
42            let line = line?;
43
44            if line.trim() == AUTOGEN_COMMENT {
45                just_fixed = true;
46                continue;
47            }
48
49            // also remove the extra newline that comes after the comment
50            if just_fixed {
51                if line.trim().is_empty() {
52                    just_fixed = false;
53                    continue;
54                }
55            }
56
57            just_fixed = false;
58            writeln!(f_fixed, "{}", line)?;
59        }
60
61        // swap the file with the newly fixed file
62        fs_err::rename(path_fix, path)?;
63    }
64
65    if found {
66        let msg = "autogenerated \"keys and their definitions\" comment";
67        if fix {
68            log::info!("fixed {} in {}", msg, path.display());
69            Ok(())
70        } else {
71            Err(anyhow!("{} in {}", msg, path.display()))
72        }
73    } else {
74        Ok(())
75    }
76}